package com.market.member.service.login;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.model.dto.LoginReqDTO;
import com.block.common.model.dto.NewMemberDTO;
import com.block.common.service.IMemberCommonService;
import com.block.common.util.StringUtil;
import com.block.common.vo.ResponseVo;
import com.block.db.entity.MemberBaseInfo;
import com.block.db.entity.WxUserBaseInfo;
import com.block.db.mapper.MemberBaseInfoMapper;
import com.block.db.mapper.WxUserBaseInfoMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.market.member.enums.UserRegTypeEnum;
import com.market.member.enums.UserTypeEnum;
import com.market.member.model.dto.LoginResultDTO;
import com.market.member.service.ILoginTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WeixinLoginServiceImpl extends ILoginTypeService {


    @Autowired
    IMemberCommonService memberCommonService;

    @Autowired
    MemberBaseInfoMapper memberBaseInfoMapper;

    @Resource
    WxUserBaseInfoMapper wxUserBaseInfoMapper;


    private final String appId="";
    private final String appSecret="";
    private static final String WX_ACCESS_TOKEN_URL = "";
    private static final String WX_USER_PHONE = "";

    private static final String WX_OPENID_URL="";

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public ResponseVo toLogin(LoginReqDTO loginReqDTO) {

        String loginCode = loginReqDTO.getLoginCode();
        //判断loginCode是否为空
        if(StringUtils.isEmpty(loginCode)){
            return new ResponseVo(AppRspCodeConstant.PARAM_ERROR, "loginCode不能为空");
        }

        //获取openid
        String openId = getOpenId(loginCode);
        //判断openid是否为空
        if(StringUtils.isEmpty(openId)){
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "openid获取失败");
        }

        //查询是否存在该用户
        WxUserBaseInfo userBaseInfo = wxUserBaseInfoMapper.selectByOpenId(openId);
        //如果不存在则创建用户信息
        if(userBaseInfo == null){
            userBaseInfo = new WxUserBaseInfo();
            userBaseInfo.setOpenId(openId);
            wxUserBaseInfoMapper.insert(userBaseInfo);
        }

        //构建参数
        boolean isNewMember = false;
        MemberBaseInfo memberInfo = null;
        //通过手机号实现微信注册
        if(ObjectUtil.isEmpty(userBaseInfo.getMobile())){
            //获取手机号
            String phone = getPhone(loginReqDTO.getMobile());
            //查看手机号是否以及存在
            MemberBaseInfo memberBaseInfo = memberBaseInfoMapper.getBaseUserInfoByPhoneLock(phone);
            //如果不存在 则实现注册
            if(ObjectUtil.isEmpty(memberBaseInfo)){
                memberBaseInfo = register(memberBaseInfo.getMobile(), loginReqDTO);
                if(ObjectUtil.isEmpty(memberBaseInfo)){
                    log.info("用户注册失败");
                    return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION,"微信登陆失败");
                }
                isNewMember = true;
            }

            //更新用户id
            WxUserBaseInfo updateUser = new WxUserBaseInfo();
            updateUser.setUid(memberBaseInfo.getUid());
            updateUser.setMobile(userBaseInfo.getMobile());
            updateUser.setOpenId(openId);
            int result = wxUserBaseInfoMapper.updateByOpenId(updateUser);
            //重新添加
            if(result > 0){
                userBaseInfo  = wxUserBaseInfoMapper.selectByOpenId(openId);
            }
        }
        if(ObjectUtil.isEmpty(memberInfo)){
            memberInfo = memberBaseInfoMapper.getMemberInfoByUidLock(userBaseInfo.getUid());
        }
        LoginResultDTO loginResultDTO = new LoginResultDTO();
        loginResultDTO.setUid(memberInfo.getUid());
        loginResultDTO.setNewMember(isNewMember);
        loginResultDTO.setMemberBaseInfo(memberInfo);

        return new ResponseVo(AppRspCodeConstant.SUCCESS, loginResultDTO);
    }

    //保存账号信息
   public MemberBaseInfo register(String mobile, LoginReqDTO loginReqDTO) {
       NewMemberDTO newMemberDTO = new NewMemberDTO();
       newMemberDTO.setMobile(mobile);
        newMemberDTO.setChannelCode(loginReqDTO.getChannelCode());
        newMemberDTO.setChannelName(loginReqDTO.getChannelName());
        newMemberDTO.setRegAppCode(loginReqDTO.getAppCode());
        newMemberDTO.setRegReqIP(loginReqDTO.getReqIp());
        newMemberDTO.setType(UserTypeEnum.NORMAL.getValue());
        newMemberDTO.setRegType(UserRegTypeEnum.NORMAL.getValue());
       return  memberCommonService.saveNewMemberInfo(newMemberDTO);
   }

    //获取openid
    public String getOpenId(String loginCode) {

        HashMap<String, Object> params = new HashMap<>();
        params.put("appid",appId);
        params.put("secret",appSecret);
        params.put("code",loginCode);
        params.put("grant_type", "authorization_code");

        try {
            String result = HttpUtil.createGet(WX_OPENID_URL).form(params).execute().body();
            JSONObject jsonObjectResult = JSON.parseObject(result);
            log.info("返回结果："+result+"openid:"+jsonObjectResult.getString("openid"));
            return jsonObjectResult.getString("openid");
        } catch (HttpException e) {
            throw new RuntimeException(e);
        }
    }

    //获取手机号
    public String getPhone(String mobileCode){
        //获取token
        String accessToken =  getAccessToken();
        if(StringUtils.isEmpty(accessToken)){
            return "无法获取到信息";
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("code",mobileCode);

        String url = WX_USER_PHONE + accessToken;
        try {
            String result = HttpUtil.createGet(url).form(params).execute().body();
            JSONObject jsonObjectResult = JSON.parseObject(result);
            log.info("返回结果："+result+"手机号"+jsonObjectResult.getJSONObject("phone_info").getString("phone"));
            if (jsonObjectResult.getInteger("errcode") == 0) {
                return jsonObjectResult.getJSONObject("phone_info").getString("phone");
            }
        } catch (HttpException e) {
            return  null;
        }

        return  null;
    }

    private String getAccessToken() {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appid", appId);
        paramMap.put("secret", appSecret);
        paramMap.put("grant_type", "client_credential");
        try {
            String result = HttpUtil.createGet(WX_ACCESS_TOKEN_URL).form(paramMap).execute().body();
            JSONObject resultObject = JSON.parseObject(result);
            log.info("返回结果："+result+"accessToken"+resultObject.getString("access_token"));
            return resultObject.getString("access_token");
        } catch (Exception e) {
            return null;
        }

    }
}
